/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package deadlocksim.gui;

import deadlocksim.*;
import deadlocksim.backend.*;
import deadlocksim.backend.process.*;
import deadlocksim.backend.resources.*;
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.lang.*;
import javax.swing.border.TitledBorder;

/**
 *
 * @author CCSCHMID
 */
public class ButtonResourceDisplay extends JPanel implements DeadlockResourceDisplay
{
    DeadlockSim mySim;
    ResourceManager resourceManager;
    GridLayout layout;
    LinkedList<ProcessButton> processButtons;
    LinkedList<ResourceTypeButton> resourceTypeButtons;
    LinkedList<JButton> resourceSumButtons;
    //JPanel cornerSpacerUL;
    JPanel cornerSpacerLL;
    JLabel timeLabel;
    LinkedList<LinkedList<ResourceUsageButton>> buttonRowList;
    int numResources;
    //int numProcesses;
    
    public ButtonResourceDisplay(DeadlockSim sim)
    {
        super(new GridLayout());
        mySim = sim;
        resourceManager = mySim.getResourceManager();
        layout = (GridLayout)this.getLayout();
        initComponents();
        
        
    }
    
    public void addResourceType(int resourceType)
    {
        ResourceTypeButton newButton 
                = new ResourceTypeButton(resourceType, mySim);
        if(resourceTypeButtons.contains(newButton))
        {
            //button already exists
            mySim.sendMessage("Resource type " + resourceType + " already loaded.", true);
            return; // Do nothing
        }
        resourceTypeButtons.add(newButton);
        numResources++;
        for(int i = 0; i < processButtons.size(); i++)
        {
            // For each process, add a corresponding resource info button for this new resource
            DeadlockProcess p = processButtons.get(i).getProcess();
            ResourceUsageButton rUsageButton = new ResourceUsageButton(p, resourceType, mySim);
                 
            LinkedList<ResourceUsageButton> buttonRow = buttonRowList.get(i);
            buttonRow.add(rUsageButton);
        }
        rebuildDisplay();
    }
    public void destroyResourceType(int resourceType)
    {
        ResourceTypeButton similarTypeButton = new ResourceTypeButton(resourceType, mySim);
        resourceTypeButtons.remove(similarTypeButton);
        ResourceUsageButton similarUsageButton = new ResourceUsageButton(null, resourceType, null);
        Iterator<LinkedList<ResourceUsageButton>> usageButtonListIter = buttonRowList.iterator();
        while(usageButtonListIter.hasNext())
        {
            LinkedList<ResourceUsageButton> aRow = usageButtonListIter.next();
            if(aRow.contains(similarUsageButton))
                aRow.remove(similarUsageButton);
        }
        numResources--;
        rebuildDisplay();
    }
    public void destroyProcess(DeadlockProcess p)
    {
        ProcessButton similarButton = new ProcessButton(p, this.mySim);
        int index = processButtons.indexOf(similarButton);
        processButtons.remove(similarButton);
        buttonRowList.remove(index);
        
        rebuildDisplay();
    }
    public void addProcess(DeadlockProcess p)
    {
        processButtons.add(new ProcessButton(p, mySim));
        //numProcesses++;
        LinkedList<ResourceUsageButton> usageButtons 
                = new LinkedList<ResourceUsageButton>();
        
        for(int i = 0; i < numResources; i++)
        {
            int resourceID = resourceTypeButtons.get(i).getResourceTypeID();
            ResourceUsageButton infoButton = new ResourceUsageButton( p, resourceID, mySim);
            usageButtons.add(infoButton);
        }
        buttonRowList.add(usageButtons);
        rebuildDisplay();
        // Refresh display
    }
    private void initComponents()
    {
        buttonRowList = new LinkedList<LinkedList<ResourceUsageButton>>();
        processButtons = new LinkedList<ProcessButton>();
        resourceTypeButtons = new LinkedList<ResourceTypeButton>();
        resourceSumButtons = new LinkedList<JButton>();
        //cornerSpacerUL = new JPanel();
        cornerSpacerLL = new JPanel();
        timeLabel = new JLabel();
        numResources = 0;
        //numProcesses = 0;
    }
    public void rebuildDisplay()
    {
        this.removeAll();
        int numColumns = 1 + resourceTypeButtons.size();
        int numRows = 1 + processButtons.size();
        layout.setColumns(numColumns);
        layout.setRows(numRows);
        //this.add(cornerSpacerUL);
        this.add(timeLabel);
        //this.add(new JLabel(""));
        for(int i = 0; i<resourceTypeButtons.size(); i++)
        {
            add(resourceTypeButtons.get(i));
        }
        for(int i = 0; i<processButtons.size(); i++)
        {
            add(processButtons.get(i));
            LinkedList<ResourceUsageButton> buttonRow = buttonRowList.get(i);
            for( int j = 0; j<buttonRow.size(); j++)
            {
                add(buttonRow.get(j));
            }
        }
    }
    
    private void refreshResourceTypeButtons()
    {
        
        int resourceNumber = resourceTypeButtons.size();
        for(int j = 0; j < resourceNumber; j++)
        {
             //System.out.println("refreshDisplay: i, j = " + i + ", " + j);
            ResourceTypeButton rTypeButton = resourceTypeButtons.get(j);
            rTypeButton.refreshDisplay();
        }
    }
    
    public void refreshDisplay(int globalTime)
    {
        int processNumber = buttonRowList.size();
        int resourceNumber = resourceTypeButtons.size();
        
        timeLabel.setText("Curr. Time = " + globalTime + " ");
        
        if(processNumber == 0 && resourceNumber > 0)
        {
            refreshResourceTypeButtons();
            validate();
            repaint();
            return;
        }
        
        for(int i = 0; i < processNumber; i++)
        {
            int resourceType, numUsed, numWanted;
            ProcessButton pb = processButtons.get(i);
            pb.refreshDisplay();
            DeadlockProcess p = pb.getProcess();
            for(int j = 0; j < resourceNumber; j++)
            {
                //System.out.println("refreshDisplay: i, j = " + i + ", " + j);
                ResourceTypeButton rTypeButton = resourceTypeButtons.get(j);
                rTypeButton.refreshDisplay();
                LinkedList<ResourceUsageButton> buttonRow = buttonRowList.get(i);
                ResourceUsageButton button = buttonRow.get(j);
                button.refreshView();
            }
        }
        validate();
        repaint();
    }
    
    public void reset()
    {
        initComponents();
        
        rebuildDisplay();
    }
    
    
}
